﻿#include "CustomeStyledDelegate.h"

#include "../Controls/DoubleSpinBox.h"
#include "../Controls/SpinBox.h"

#include <QComboBox>

namespace GeneralUI {

	ReadOnlyDelegate::ReadOnlyDelegate(QObject *parent /*= 0*/)
		: QStyledItemDelegate(parent)
	{

	}

	ReadOnlyDelegate::~ReadOnlyDelegate()
	{

	}

	QWidget* ReadOnlyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
	{
		Q_UNUSED(parent)
			Q_UNUSED(option)
			Q_UNUSED(index)

			return NULL;
	}

	CreateSpinBoxDelegate::CreateSpinBoxDelegate(QObject *parent /*= nullptr*/, SpinBoxDelegateType type /*= TYPE_DBSPINBOX*/, double minValue /*= 99999.0*/, double maxValue /*= -99999.0*/)
		: QStyledItemDelegate(parent)
		, m_delegateType(type)
		, m_minValue(minValue)
		, m_maxValue(maxValue)
		, m_decimals(2)
		, m_commitDataImmediately(false)
	{

	}

	CreateSpinBoxDelegate::~CreateSpinBoxDelegate()
	{

	}

	void CreateSpinBoxDelegate::setDecimals(int decimals)
	{
		if (m_decimals != decimals)
		{
			m_decimals = decimals;
		}
	}

	QWidget* CreateSpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
	{
		Q_UNUSED(option)

			if (!index.isValid())
				return nullptr;

		QWidget *widget = nullptr;
		SpinBox *spinBox = nullptr;
		DoubleSpinBox *dbSpinBox = nullptr;

		switch (m_delegateType)
		{
		case SpinBoxDelegateType::TYPE_SPINBOX:
			spinBox = new SpinBox(parent);
			spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
			spinBox->setMaximum(m_maxValue);
			spinBox->setMinimum(m_minValue);
			spinBox->setFrame(false);
			connect(spinBox, &SpinBox::editingFinished, this, &CreateSpinBoxDelegate::commitDataFunc);
			widget = qobject_cast<QWidget *>(spinBox);
			break;
		case SpinBoxDelegateType::TYPE_DBSPINBOX:
			dbSpinBox = new DoubleSpinBox(parent);
			dbSpinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
			dbSpinBox->setMaximum(m_maxValue);
			dbSpinBox->setMinimum(m_minValue);
			dbSpinBox->setDecimals(m_decimals);
			dbSpinBox->setFrame(false);
			connect(dbSpinBox, &DoubleSpinBox::editingFinished, this, &CreateSpinBoxDelegate::commitDataFunc);
			widget = qobject_cast<QWidget *>(dbSpinBox);
			break;
		default:
			Q_ASSERT(false);
			break;
		}

		return widget;
	}

	void CreateSpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
	{
		Q_UNUSED(index)

			editor->setGeometry(option.rect);
	}

	void CreateSpinBoxDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
	{
		SpinBox *spinBox = nullptr;
		DoubleSpinBox *dbSpinBox = nullptr;
		double value;

		switch (m_delegateType)
		{
		case SpinBoxDelegateType::TYPE_SPINBOX:
			spinBox = qobject_cast<SpinBox*>(editor);
			spinBox->setValue(index.data(Qt::EditRole).toInt());
			break;
		case SpinBoxDelegateType::TYPE_DBSPINBOX:
			dbSpinBox = qobject_cast<DoubleSpinBox*>(editor);
			value = index.data(Qt::EditRole).toDouble();
			dbSpinBox->setValue(value);
			break;
		default:
			break;
		}
	}

	void CreateSpinBoxDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
	{
		SpinBox *spinBox = nullptr;
		DoubleSpinBox *dbSpinBox = nullptr;

		switch (m_delegateType)
		{
		case SpinBoxDelegateType::TYPE_SPINBOX:
			spinBox = qobject_cast<SpinBox*>(editor);
			model->setData(index, spinBox->value(), Qt::DisplayRole);
			break;
		case SpinBoxDelegateType::TYPE_DBSPINBOX:
			dbSpinBox = qobject_cast<DoubleSpinBox*>(editor);
			model->setData(index, dbSpinBox->value(), Qt::DisplayRole);
			break;
		default:
			break;
		}
	}

	void CreateSpinBoxDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
	{
		QStyledItemDelegate::paint(painter, option, index);
	}

	void CreateSpinBoxDelegate::commitDataFunc()
	{
		if (!m_commitDataImmediately)
		{
			return;
		}

		QWidget *w = qobject_cast<QWidget*>(sender());
		Q_ASSERT(w);

		emit commitData(w);
	}

	CreateComboBoxDelegate::CreateComboBoxDelegate(QObject *parent/* = nullptr*/)
		: QStyledItemDelegate(parent)
	{
	}

	CreateComboBoxDelegate::~CreateComboBoxDelegate()
	{
	}

	QWidget * CreateComboBoxDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
	{
		Q_UNUSED(option)

			if (!index.isValid())
				return nullptr;

		QStringList itemList = index.data(ID_COMBOBOX_ITEMLIST).toStringList();

		QComboBox *comboBox = new QComboBox(parent);
		comboBox->addItems(itemList);
		comboBox->setFrame(false);

		return comboBox;
	}

	void CreateComboBoxDelegate::updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const
	{
		Q_UNUSED(index)

			editor->setGeometry(option.rect);
	}

	void CreateComboBoxDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
	{
		QStringList itemList = index.data(ID_COMBOBOX_ITEMLIST).toStringList();
		int num = itemList.indexOf(index.data(Qt::DisplayRole).toString());
		QComboBox *comboBox = static_cast<QComboBox*>(editor);
		comboBox->setCurrentIndex(num);
	}

	void CreateComboBoxDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
	{
		QStringList itemList = index.data(ID_COMBOBOX_ITEMLIST).toStringList();
		QComboBox *comboBox = static_cast<QComboBox*>(editor);
		int i = comboBox->currentIndex();
		model->setData(index, itemList[comboBox->currentIndex()], Qt::DisplayRole);
	}

	void CreateComboBoxDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
	{
		QStyledItemDelegate::paint(painter, option, index);
	}

}//namespace OfUI
